package org.example.gradlegateway.filter;

import gradle.common.core.enums.ResultCodeEnum;
import gradle.common.core.exception.InvalidBearerTokenException;
import gradle.common.core.utils.JsonUtil;
import org.example.gradlegateway.model.ResponseEntity;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.oauth2.jwt.JwtException;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.resource.NoResourceFoundException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Component
@Order(-1)  // 确保优先级高于默认的 DefaultErrorWebExceptionHandler
public class GlobalErrorWebExceptionHandler implements ErrorWebExceptionHandler {

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        if (ex instanceof NoResourceFoundException) {
            //未发现注册的服务路由
            exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);

            Map<String, Object> stringObjectHashMap = new HashMap<>();
            stringObjectHashMap.put("timestamp", LocalDateTime.now());
            stringObjectHashMap.put("status", HttpStatus.NOT_FOUND.value());
            stringObjectHashMap.put("error", "invalid resource path");
            stringObjectHashMap.put("path", exchange.getRequest().getPath().value());


            return exchange.getResponse()
                    .writeWith(Mono.just(exchange.getResponse()
                            .bufferFactory()
                            .wrap(JsonUtil.toJsonString(stringObjectHashMap).getBytes())));
        }

        //token 校验异常
        if (ex instanceof InvalidBearerTokenException || ex instanceof JwtException) {
            exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);

            ResponseEntity responseEntity = new ResponseEntity(ResultCodeEnum.ACCOUNT_EXPIRED.getCode(), ResultCodeEnum.ACCOUNT_EXPIRED.getMessage());

            return exchange.getResponse()
                    .writeWith(Mono.just(exchange.getResponse()
                            .bufferFactory()
                            .wrap(JsonUtil.toJsonString(responseEntity).getBytes())));
        }
        // 其他异常交给默认处理器处理
        return Mono.error(ex);
    }
}